package com.augurit.smartform.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.base.form.Attachment;
import com.augurit.common.util.PageUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.smartform.constant.ComponentConstant;
import com.augurit.smartform.converter.ComponentDefinitionConverter;
import com.augurit.smartform.dao.SmComponentDefinitionDao;
import com.augurit.smartform.entity.SmComponentDefinition;
import com.augurit.smartform.exception.FormException;
import com.augurit.smartform.service.IComponentDefinitionService;
import com.augurit.smartform.service.IComponentRegisterService;
import com.augurit.smartform.web.component.form.ComponentDefinitionForm;
import com.augurit.smartform.web.component.form.ComponentRegisterForm;

@Service
@Transactional
public class ComponentDefinitionService implements IComponentDefinitionService {
	@Autowired
	private SmComponentDefinitionDao componentDefinitionDao;
	@Autowired
	private IComponentRegisterService componentRegisterService;
	
	/**
	 * 根据主键获取Form对象
	 */
	@Transactional(readOnly = true)
	public ComponentDefinitionForm get(Long id){
		SmComponentDefinition entity=componentDefinitionDao.get(id);
		ComponentDefinitionForm form=ComponentDefinitionConverter.convertToForm(entity);
		return form;
	}
	
	/**
	 * 根据组件目录ID查询组件
	 * @param registerId
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<ComponentDefinitionForm> getDefinitionByRegisterId(Long registerId){
		List<SmComponentDefinition> list=componentDefinitionDao.getDefinitionByRegisterId(registerId);
		return ComponentDefinitionConverter.convertToFormList(list);
	}
	
	/**
	 * 根据分页对象和Form对象进行分页条件查询
	 * @param page 分页对象
	 * @param form Form对象
	 * @return 分页查询结果.附带结果列表及所有查询时的参数
	 */
	@Transactional(readOnly = true)
	public Page<ComponentDefinitionForm> search(Page<ComponentDefinitionForm> page, ComponentDefinitionForm form) {
		// 建立新的分页对象
		Page pg = PageUtils.newPageInstance(page);
		
		// 查询语句及参数
		StringBuffer hql = new StringBuffer("from SmComponentDefinition scd where 1 = 1 ");
		List<Object> values = new ArrayList();
		
		if(form != null){
			if(StringUtils.isNotBlank(form.getTag())){
				hql.append(" and scd.tag like ?");
				values.add("%" + form.getTag() + "%");
			}
			if(StringUtils.isNotBlank(form.getCreatePerson())){
				hql.append(" and scd.createPerson like ?");
				values.add("%" + form.getCreatePerson() + "%");
			}
			if(StringUtils.isNotBlank(form.getAvailable())){
				hql.append(" and scd.available = ?");
				values.add(form.getAvailable());
			}
			if(StringUtils.isNotBlank(form.getTagCn())){
				hql.append(" and scd.tagCn like ?");
				values.add("%" + form.getTagCn() + "%");
			}
			if(form.getRegisterId()!=null){
				hql.append(" and scd.registerId = ?");
				values.add(form.getRegisterId());
			}
			if(form.getId()!=null){
				hql.append(" and scd.id = ?");
				values.add(form.getId());
			}
		}
		
		// 执行分页查询操作
		componentDefinitionDao.findPage(pg, hql.toString(), values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<ComponentDefinitionForm> forms=ComponentDefinitionConverter.convertToFormList(pg.getResult());
		PageUtils.copy(pg, forms, page);
		
		return page;
	}
	
	/**
	 * 禁用某个组件目录下面的所有组件
	 * @param registerId
	 */
	public void disableByRegisterId(Long registerId){
		componentDefinitionDao.disableByRegisterId(registerId);
	}
	
	/**
	 * 启用某个组件目录下面的所有组件
	 * @param registerId
	 */
	public void enableByRegisterId(Long registerId){
		componentDefinitionDao.enableByRegisterId(registerId);
	}
	
	/**
	 * 处理组件定义XML文件并注册组件
	 * @param attachment
	 * @param form
	 */
	public void handleXmlFile(Attachment attachment,ComponentDefinitionForm form) throws FormException{
		this.setValueByFile(attachment.getFile(),form);
		SmComponentDefinition entity=null;
		SmComponentDefinition oldEntity=componentDefinitionDao.getDefinitionByTag(form.getTag());
		if(oldEntity!=null&&oldEntity.getTag().equals(form.getTag())&&!oldEntity.getId().equals(form.getId())){
			throw new FormException("TAG为'"+form.getTag()+"'的组件已存在");
		}else{
			if(form.getId()==null){
				entity=new SmComponentDefinition();
				ComponentDefinitionConverter.convertToEntity(form, entity);
			}else{
				entity=componentDefinitionDao.get(form.getId());
				ComponentDefinitionConverter.convertToEntity(form, entity);
			}
		}
		componentDefinitionDao.save(entity);
		
		ComponentDefinitionForm newForm=this.get(entity.getId());
		componentRegisterService.regist(newForm);
	}
	
	/**
	 * 更新组件图标
	 * @param form
	 */
	public void updateIcon(ComponentDefinitionForm form) throws FormException{
		if(this.checkRegistEnable(form)){
			this.save(form);
			componentRegisterService.regist(form);
		}else{
			throw new FormException("修改组件图标失败，请先启动组件");
		}
	}
	
	/**
	 * 保存组件
	 * @param form
	 */
	public void save(ComponentDefinitionForm form){
		SmComponentDefinition entity=null;
		if(form.getId()==null){
			entity=new SmComponentDefinition();
			ComponentDefinitionConverter.convertToEntity(form, entity);
		}else{
			entity=componentDefinitionDao.get(form.getId());
			ComponentDefinitionConverter.convertToEntity(form, entity);
		}
		componentDefinitionDao.save(entity);
	}
	
	/**
	 * 禁用组件
	 * @param form
	 */
	public void disable(ComponentDefinitionForm form) throws FormException{
		if(this.checkRegistEnable(form)){
			if("1".equals(form.getAvailable())){
				componentRegisterService.unRegist(form);
				
				SmComponentDefinition entity=componentDefinitionDao.get(form.getId());
				entity.setAvailable("0");
				componentDefinitionDao.save(entity);
			}else{
				throw new FormException("组件已经禁用");
			}
		}else{
			throw new FormException("组件禁用失败，请先启用组件注册目录");
		}
	}
	
	/**
	 * 删除组件
	 * @param form
	 */
	public void delete(ComponentDefinitionForm form){
		componentRegisterService.unRegist(form);
				
		SmComponentDefinition entity=componentDefinitionDao.get(form.getId());
		componentDefinitionDao.delete(entity);
	}
	
	/**
	 * 启用组件
	 * @param form
	 */
	public void enable(ComponentDefinitionForm form) throws FormException{
		if(this.checkRegistEnable(form)){
			if("0".equals(form.getAvailable())){
				componentRegisterService.regist(form);
				
				SmComponentDefinition entity=componentDefinitionDao.get(form.getId());
				entity.setAvailable("1");
				componentDefinitionDao.save(entity);
			}else{
				throw new FormException("组件已经启用");
			}
		}else{
			throw new FormException("组件启用失败，请先启用组件注册目录");
		}
	}
	
	/**
	 * 拖拽组件
	 * @param form
	 */
	public void dragComponent(ComponentDefinitionForm form) throws FormException{
		if("1".equals(form.getAvailable())){
			ComponentDefinitionForm originalForm=this.get(form.getId());
			componentRegisterService.unRegist(originalForm);
			this.save(form);
			componentRegisterService.regist(form);
		}else{
			throw new FormException("组件拖拽失败，请先启用组件注册目录");
		}
	}
	
	/**
	 * 获得表单所有可用的组件
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map> getAllAvailableComponent(){
		return componentDefinitionDao.getAllAvailabeComponent();
	}
	
	/**
	 * 校验并设置FORM的属性值
	 * @param file
	 * @param form
	 * @throws FormException
	 */
	private void setValueByFile(File file,ComponentDefinitionForm form) throws FormException{
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(file);
			List<Element> root=(List<Element>)document.selectNodes("/component");
			if(root!=null&&root.size()>0){
				Element element=root.get(0);
				String cnname=element.attributeValue("cnname");
				if(StringUtils.isNotBlank(cnname)){
					form.setTagCn(cnname);
				}else{
					throw new FormException("未指定'cnname'属性的值");
				}
				String htmlTag=element.attributeValue("htmlTag");
				if(StringUtils.isBlank(htmlTag)){
					throw new FormException("未指定'htmlTag'属性的值");
				}
				String hasModel=element.attributeValue("hasModel");
				if(StringUtils.isBlank(hasModel)||!"true".equals(hasModel)&&!"false".equals(hasModel)){
					throw new FormException("'hasModel'属性的值必须是true或者false");
				}else if("true".equals(hasModel)){
					form.setHasModel(true);
				}else if("false".equals(hasModel)){
					form.setHasModel(false);
				}
				String hasHtmlContent=element.attributeValue("hasHtmlContent");
				if("true".equals(hasHtmlContent)){
					form.setIsView("1");
				}else if("false".equals(hasHtmlContent)){
					form.setIsView("0");
				}else{
					throw new FormException("'hasHtmlContent'属性的值必须是true或者false");
				}
			}else{
				throw new FormException("上传文件的根元素不是'component'元素");
			}
			if(form.getHasModel()){
				List<Element> idElements=(List<Element>)document.selectNodes("/component/property[@name=\"id\"]");
				if(idElements!=null&&idElements.size()>0){
					Element element=idElements.get(0);
					String htmlFieldVal=element.attributeValue("htmlField");
					if(!"true".equals(htmlFieldVal)){
						throw new FormException("ID元素的'htmlTag'属性值不为'true'");
					}
				}else{
					throw new FormException("未指定'name'属性值为'id'的'property'元素");
				}
			}
			List<Element> tagElements=(List<Element>)document.selectNodes("/component/property[@name=\"tag\"]");
			if(tagElements!=null&&tagElements.size()>0){
				Element element=tagElements.get(0);
				if(form.getHasModel()){
					String htmlFieldVal=element.attributeValue("htmlField");
					if(!"true".equals(htmlFieldVal)){
						throw new FormException("TAG元素的'htmlTag'属性值不为'true'");
					}
				}
				String tagVal=element.attributeValue("value");
				if(StringUtils.isNotBlank(tagVal)){
					form.setTag(tagVal);
				}else{
					throw new FormException("未指定TAG元素的'value'属性值");
				}
			}else{
				throw new FormException("未指定'name'属性值为'tag'的'property'元素");
			}
			form.setAvailable("1");
			if(form.getId()!=null){
				form.setEditTime(new Date());
			}else{
				form.setCreateTime(new Date());
			}
			form.setContent(document.asXML());
			form.setIcon(ComponentConstant.ICON_DEFAULT);
		} catch (DocumentException e) {
			e.printStackTrace();
			throw new FormException("上传文件无法打开或者不是XML类型的文件");
		}
	}
	
	/**
	 * 检查组件注册目录是否启用
	 * @param form
	 * @return
	 */
	private boolean checkRegistEnable(ComponentDefinitionForm form){
		boolean flag=false;
		ComponentRegisterForm registerForm=componentRegisterService.get(form.getRegisterId());
		if("1".equals(registerForm.getAvailable())){
			flag=true;
		}
		return flag;
	}
}
